/*
 * @Description: 针对业务封装的一些地图函数, 标记点等地图样式在map.scss
 * @Author: liushuang
 * @Date: 2022-05-10 11:34:58
 * @LastEditTime: 2022-12-02 19:34:33
 */
import { getPolygonCenter } from '@/utils/utils'

const mapUtils = (AMapBase, map) => ({
  /**
   * @desc: 生成告警聚合点
   * @param {*} points [{lnglat: [xx,xx]}]
   */
  createAlarmCluster(points) {
    return new AMapBase.value.MarkerCluster(map.value, points, {
      gridSize: 80,
      maxZoom: 20,
      averageCenter: true,
      renderClusterMarker: this.renderClusterAlarmMarker,
      renderMarker: this.renderAlarmMarker
    })
  },
  /**
   * @desc: 自定义告警聚合点样式
   * @param {*} context
   */
  renderClusterAlarmMarker(context) {
    const content = `<div class='videoMarker cluster alarm'><div class='icon'><span class='fa fa-video-camera'></span></div><div class='title'>告警总数：${context.count}</div></div>`
    context.marker.setContent(content)
  },
  /**
   * @desc: 自定义告警非聚合点样式
   * @param {*} context
   */
  renderAlarmMarker(context) {
    const content = `<div class='videoMarker alarm'><div class='icon'><span class='fa fa-video-camera'></span></div><div class='title'>${
      context.data[0].alarmName || context.data[0].name
    }</div></div>`
    context.marker.setContent(content)
  },
  /**
   * @desc: 生成告警
   * @param {Object} point
   * @param {Array} FnList
   */
  createMarkerAlarm(point, FnList) {
    const content = `<div class='videoMarker alarm' item='${JSON.stringify(
      point
    )}'><div class='icon'><span class='fa fa-video-camera'></span></div><div class='title'>${
      point.alarmName || point.name
    }</div></div>`
    const marker = new AMapBase.value.Marker({
      content,
      position: [point.longitude, point.latitude],
      topWhenClick: true
    })
    this.bindEvent(marker, FnList)
    return marker
  },
  /**
   * @desc: 地图缩放到指定范围
   * @param {*} map 地图实例
   * @param {Array} arr 要包括的元素
   * @param {Boolean} immediately 是否立即过渡 是：没有动画效果
   * @param {Array} padding 四周边距，上、下、左、右
   * @param {Number} maxZoom 最大缩放级别
   */
  setFitView(
    arr,
    immediately = true,
    padding = [60, 60, 60, 60],
    maxZoom = 17
  ) {
    map.value.setFitView(arr, immediately, padding, maxZoom)
  },
  /**
   * @desc: 返回正确的坐标点 对聚合点不适用
   * @param {*} point
   */
  setPosition(point) {
    return Array.isArray(point) ? point : point.lnglat || [point.lng, point.lat]
  },
  /**
   * @desc: 绑定标记点事件集合
   * @param {*} marker 标记点
   * @param {Array} FnList 事件集合 { type: 'click | ....', fn: 事件 }
   */
  bindEvent(marker, FnList) {
    if (FnList && FnList.length > 0) {
      FnList.forEach((Fn) => {
        marker.on(Fn.type, Fn.fn, Fn.context)
      })
    }
  },
  /**
   * @desc: 销毁标记点事件集合
   * @param {*} marker
   * @param {*} FnList
   */
  removeEvent(marker, FnList) {
    if (FnList && FnList.length > 0) {
      FnList.forEach((Fn) => {
        marker.off(Fn.type, Fn.fn)
      })
    }
  },
  /**
   * @desc: 判断地图上两个多边形是否相交
   * @param {*} targetPath
   * @param {*} path
   */
  doesRingRingIntersect(targetPath, path) {
    return AMapBase.value.GeometryUtil.doesRingRingIntersect(targetPath, path)
  },

  /**
   * @desc: 判断地图上两个多边形target是否在path内
   * @param {*} targetPath
   * @param {*} path
   */
  isRingInRing(targetPath, path) {
    return AMapBase.value.GeometryUtil.isRingInRing(targetPath, path)
  },
  /**
   * @desc: 判断中心点是否在边界内
   * @return {Boolean}
   */
  markerInPoly(position, path) {
    return AMapBase.value.GeometryUtil.isPointInRing(position, path)
  },
  /**
   * @desc: 创建多边形
   * @return {*}
   */
  createPolygon(path, color) {
    return new AMapBase.value.Polygon({
      path,
      zIndex: -1,
      fillColor: color,
      fillOpacity: 0.2,
      strokeColor: color,
      strokeOpacity: 0.7,
      strokeWeight: 3
    })
  },
  /**
   * @desc: 创建折线
   * @return {*}
   */
  createPolyline(path, color) {
    return new AMapBase.value.Polyline({
      path,
      isOutline: true,
      outlineColor: '#fff',
      borderWeight: 2,
      strokeColor: color,
      strokeOpacity: 0.9,
      strokeWeight: 5,
      strokeStyle: 'solid',
      lineJoin: 'round',
      lineCap: 'round',
      zIndex: 50
    })
  },
  /**
   * @desc: 校区
   * @param {String} name 名称
   * @param {Array} point 中心点
   * @param {Array} path 多边形点位
   * @param {String} color 多边形颜色
   * @return {Object} {optionMarker,nameMarker}
   */
  SCHOOL_CAMPUS({
    name, point, path, color = '#1791fc', draggable = false
  }) {
    let optionMarker = null
    let nameMarker = null
    if (path) {
      optionMarker = this.createPolygon(path, color)
    }
    const content = "<div class='fa fa-map-marker schoolOptionMarker'></div>"
    if (point) {
      // 坐标点
      nameMarker = new AMapBase.value.Marker({
        content,
        position: point,
        offset: new AMapBase.value.Pixel(-13, -30),
        draggable
      })
      if (name) {
        // 坐标点校区描述
        nameMarker.setLabel({
          direction: 'top',
          offset: new AMapBase.value.Pixel(0, -3),
          content: `<div class='schoolOptionLabel'>${name}</div>`
        })
      }
    }
    return {
      optionMarker,
      nameMarker
    }
  },
  /**
   * @desc: 区域
   * @param {String} name 名称
   * @param {Array} path 多边形点位
   * @param {String} color 多边形颜色
   * @return {Object} {optionMarker,nameMarker}
   */
  SCHOOL_DISTRICT({
    name, path, color = '1791fc', onlyName = false
  }) {
    let optionMarker = null
    let nameMarker = null
    if (path) {
      if (!onlyName) {
        optionMarker = this.createPolygon(path, color)
      }
      if (name) {
        const content = `<div class='areaNameMarker'><div class='main' style='background:${color}'></div>${name}</div>`
        // 坐标点
        nameMarker = new AMapBase.value.Marker({
          content,
          position: getPolygonCenter(path)
        })
      }
    }
    return {
      optionMarker,
      nameMarker
    }
  },
  /**
   * @desc: 楼宇
   * @param {String} name 名称
   * @param {Array} point 楼宇点位
   * @return {Object} {optionMarker}
   */
  SCHOOL_BUILDING({ name, point }) {
    let optionMarker = null
    const content = "<div class='fa fa-map-marker buildingOptionMarker'></div>"
    if (point) {
      // 坐标点
      optionMarker = new AMapBase.value.Marker({
        content,
        position: point,
        offset: new AMapBase.value.Pixel(-5, -15)
      })
      if (name) {
        optionMarker.setLabel({
          direction: 'top',
          offset: new AMapBase.value.Pixel(0, -3),
          content: `<div class='buildingOptionLabel'>${name}</div>`
        })
      }
    }
    return {
      optionMarker
    }
  },
  /**
   * @desc: 道路
   * @param {String} name 名称
   * @param {Array} path 道路点位
   * @param {String} color 道路颜色
   * @return {Object} {optionMarker,nameMarker}
   */
  SCHOOL_ROAD({
    name, path, color, onlyName = false
  }) {
    let optionMarker = null
    let nameMarker = null
    if (path) {
      if (!onlyName) {
        optionMarker = this.createPolyline(path, color)
      }
      if (name) {
        const content = `<div class='roadNameMarker'><div class='main' style='background:${color}'></div>${name}</div>`
        // 坐标点
        nameMarker = new AMapBase.value.Marker({
          content,
          position: path[0],
          draggable: false,
          topWhenClick: true,
          offset: new AMapBase.value.Pixel(0, 30)
        })
      }
    }
    return {
      optionMarker,
      nameMarker
    }
  },
  /**
   * @desc: 出入口
   * @param {String} name 名称
   * @param {Array} point 出入口点位
   * @return {Object} {optionMarker}
   */
  SCHOOL_PASSAGEWAY({ name, point }) {
    let optionMarker = null
    if (point) {
      const content = "<div class='fa fa-retweet gateOptionMarker'></div>"
      // 坐标点
      optionMarker = new AMapBase.value.Marker({
        content,
        position: point,
        offset: new AMapBase.value.Pixel(-14, -13)
      })
      if (name) {
        // 坐标点描述
        optionMarker.setLabel({
          direction: 'top',
          offset: new AMapBase.value.Pixel(0, -3),
          content: `<div class='gateOptionLabel'>${name}</div>`
        })
      }
    }
    return {
      optionMarker
    }
  }
})

export default mapUtils
